/*
 *  Copyright 2010 Susanta Tewari.
 *  This file is part of genomemap.
 * 
 *  genomemap is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *  
 *  genomemap is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License
 *  along with genomemap.  If not, see <http://www.gnu.org/licenses/>.
 */
package genomemap.queries;

import genomemap.data.CacheManager;
import genomemap.data.Chromosome;
import genomemap.data.GWData;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @version 1.0 Apr 20, 2010
 * @author Susanta Tewari
 */
public class SummaryStat extends Query {

    List<ChSummaryStat> chSummaries = new ArrayList<ChSummaryStat>();

    Set<String> cloneSeq;

    Set<String> geneSeq;

    public SummaryStat() {

        GWData gwData = GWData.getInstance();
        cloneSeq = gwData.getClones();
        geneSeq = gwData.getGenes();
    }

    /**
     * 
     * @return
     */
    public Object getDataModel() {
        Map root = new HashMap();

        // summary for input data
        for (Integer linkageGroup : GWData.getInstance().getLinkageGroups())
            this.add(linkageGroup);

        // summary for test data
        CacheManager.getInstance().changeData(
                QueryRunner.getInstance().getProperty("testdata.jar"),
                QueryRunner.getInstance().getProperty("test.linkage.groups"));

        SummaryStat testSummaryStat = new SummaryStat();
        for (Integer linkageGroup : GWData.getInstance().getLinkageGroups())
            testSummaryStat.add(linkageGroup);

        // change the data back to input data
        CacheManager.getInstance().changeData(
                QueryRunner.getInstance().getProperty("data.jar"),
                QueryRunner.getInstance().getProperty("linkage.groups"));

        root.put("inputSummaryStat", this);
        root.put("testSummaryStat", testSummaryStat);

        return root;
    }

    public void add(Integer linkageGroup) {

        ChSummaryStat chSummaryStat = new ChSummaryStat();

        Chromosome chr = Chromosome.getInstance(linkageGroup);

        Set<String> probes = chr.getProbes();
        Set<String> clones = chr.getClones();
        Set<String> genes = chr.getGenes();

        chSummaryStat.setLinkageGroup(linkageGroup);
        chSummaryStat.setCloneCount(clones.size());
        chSummaryStat.computeSRAClones(clones);
        chSummaryStat.setCloneSeqCount(count(clones, cloneSeq));
        chSummaryStat.setProbeCount(probes.size());
        chSummaryStat.setProbeSeqCount(count(probes, cloneSeq));
        chSummaryStat.setGeneCount(genes.size());
        chSummaryStat.setGeneSeqCount(count(genes, geneSeq));
        chSummaryStat.setGenesAssignmentCount(chr.getGenesTagged().size());

        chSummaries.add(chSummaryStat);
    }

    /**
     * find how many elements of c1 are in c2
     * @param c1
     * @param c2
     * @return
     */
    private int count(Collection<String> c1, Collection<String> c2) {

        int result = 0;

        for (String val : c1) {
            if (c2.contains(val)) result++;
        }

        return result;
    }

    public List<ChSummaryStat> getChSummaries() {
        return chSummaries;
    }

    public Integer getTotalCloneCount() {

        int result = 0;

        for (ChSummaryStat chSummaryStat : chSummaries) {
            result += chSummaryStat.getCloneCount();
        }

        return result;
    }

    public Integer getTotalCloneSeqCount() {

        int result = 0;

        for (ChSummaryStat chSummaryStat : chSummaries) {
            result += chSummaryStat.getCloneSeqCount();
        }

        return result;
    }

    public Integer getTotalsCloneCount() {

        int result = 0;

        for (ChSummaryStat chSummaryStat : chSummaries) {
            result += chSummaryStat.getsCloneCount();
        }

        return result;
    }

    public Integer getTotalrCloneCount() {

        int result = 0;

        for (ChSummaryStat chSummaryStat : chSummaries) {
            result += chSummaryStat.getrCloneCount();
        }

        return result;
    }

    public Integer getTotalaCloneCount() {

        int result = 0;

        for (ChSummaryStat chSummaryStat : chSummaries) {
            result += chSummaryStat.getaCloneCount();
        }

        return result;
    }

    public Integer getTotalProbeCount() {

        int result = 0;

        for (ChSummaryStat chSummaryStat : chSummaries) {
            result += chSummaryStat.getProbeCount();
        }

        return result;
    }

    public Integer getTotalProbeSeqCount() {

        int result = 0;

        for (ChSummaryStat chSummaryStat : chSummaries) {
            result += chSummaryStat.getProbeSeqCount();
        }

        return result;
    }

    public Integer getTotalGeneCount() {

        int result = 0;

        for (ChSummaryStat chSummaryStat : chSummaries) {
            result += chSummaryStat.getGeneCount();
        }

        return result;
    }

    public Integer getTotalGeneSeqCount() {

        int result = 0;

        for (ChSummaryStat chSummaryStat : chSummaries) {
            result += chSummaryStat.getGeneSeqCount();
        }

        return result;
    }

    public Integer getTotalGenesAssignmentCount() {

        int result = 0;

        for (ChSummaryStat chSummaryStat : chSummaries) {
            result += chSummaryStat.getGenesAssignmentCount();
        }

        return result;
    }

    public class ChSummaryStat {

        int linkageGroup;

        int cloneCount;

        int cloneSeqCount;

        /**
         * a clone with no repeats
         */
        int sCloneCount;

        /**
         * a clone with repeats in more than 1 but not in all linkage groups considered
         */
        int rCloneCount;

        /**
         * a clone with repeats in all linkage groups considered
         */
        int aCloneCount;

        int probeCount;

        int probeSeqCount;

        int geneCount;

        int geneSeqCount;

        int genesAssignmentCount;

        void computeSRAClones(Set<String> clones) {

            aCloneCount = rCloneCount = sCloneCount = 0;

            GWData gwData = GWData.getInstance();
            int totalLinkageGroups = GWData.getInstance().getLinkageGroups().size();

            for (String clone : clones) {

                int repeatCount = gwData.getRepeatCount(clone);

                if (repeatCount == 1) sCloneCount++;
                else if (repeatCount == totalLinkageGroups) aCloneCount++;
                else rCloneCount++;
            }

        }

        // <editor-fold defaultstate="collapsed" desc="Properties">
        public Integer getCloneCount() {
            return cloneCount;
        }

        public void setCloneCount(Integer cloneCount) {
            this.cloneCount = cloneCount;
        }

        public Integer getCloneSeqCount() {
            return cloneSeqCount;
        }

        public void setCloneSeqCount(Integer cloneSeqCount) {
            this.cloneSeqCount = cloneSeqCount;
        }

        public Integer getaCloneCount() {
            return aCloneCount;
        }

        public Integer getrCloneCount() {
            return rCloneCount;
        }

        public Integer getsCloneCount() {
            return sCloneCount;
        }

        public Integer getGeneCount() {
            return geneCount;
        }

        public void setGeneCount(Integer geneCount) {
            this.geneCount = geneCount;
        }

        public Integer getGeneSeqCount() {
            return geneSeqCount;
        }

        public void setGeneSeqCount(Integer geneSeqCount) {
            this.geneSeqCount = geneSeqCount;
        }

        public Integer getGenesAssignmentCount() {
            return genesAssignmentCount;
        }

        public void setGenesAssignmentCount(Integer genesTaggedCOunt) {
            this.genesAssignmentCount = genesTaggedCOunt;
        }

        public Integer getLinkageGroup() {
            return linkageGroup;
        }

        public void setLinkageGroup(Integer linkageGroup) {
            this.linkageGroup = linkageGroup;
        }

        public Integer getProbeCount() {
            return probeCount;
        }

        public void setProbeCount(Integer probeCount) {
            this.probeCount = probeCount;
        }

        public Integer getProbeSeqCount() {
            return probeSeqCount;
        }

        public void setProbeSeqCount(Integer probeSeqCount) {
            this.probeSeqCount = probeSeqCount;
        }// </editor-fold>

    }
}
